package model.core.torneo;

import model.core.utente.AbstractDomainModelObservable;
import model.core.utente.Giocatore;
import model.core.utente.GiocatoreInterface;
import model.core.utente.Squadra;
import model.utility.Constants;
import model.utility.Utility;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * 
 * @author Giuseppe Fusco (fusgius19@gmail.com)
 *
 */
public class Classifica extends AbstractDomainModelObservable {

	private ArrayList<GiocatoreInterface> giocatori;
	private Comparator<GiocatoreInterface> comparator;
	private int maxComponenti=Constants.default_max_componenti_torneo, minComponenti=Constants.default_min_componenti_torneo;

	public Classifica(int maxComponenti, int minComponenti){
		if(maxComponenti>=Constants.default_max_componenti_torneo && 
				minComponenti>=Constants.default_min_componenti_torneo && maxComponenti>=minComponenti){
			this.maxComponenti = maxComponenti;
			this.minComponenti = minComponenti;
		}
		giocatori = new ArrayList<GiocatoreInterface>();
		comparator = new Comparator<GiocatoreInterface>() {
			/* (non-Javadoc)
			 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
			 */
			@Override
			public int compare(GiocatoreInterface arg0, GiocatoreInterface arg1) {
				// TODO Auto-generated method stub
				return arg0.getTotale_punti()-arg1.getTotale_punti();
			}
		};
	}

	public int getMaxComponenti() {
		return maxComponenti;
	}

	public int getMinComponenti() {
		return minComponenti;
	}

	public void setMaxComponenti(int maxComponenti) {
		if(maxComponenti>=2 && maxComponenti>=this.minComponenti)
			this.maxComponenti = maxComponenti;
	}

	public void setMinComponenti(int minComponenti) {
		if(minComponenti>=2 && minComponenti<=this.maxComponenti)
			this.minComponenti = minComponenti;
	}

	public void ordina() {
		if(comparator!=null && giocatori!=null && giocatori.size()>0)
			Collections.sort(giocatori, comparator);
	}

	public boolean addGiocatore(GiocatoreInterface giocatore, boolean isSingolo) {
		if(isSingolo && (giocatore instanceof Giocatore))
		{
			try {
				boolean v = 
						!Utility.isThereGiocatore(giocatori, giocatore) && 
						giocatori.size()<maxComponenti &&
						giocatori.add(giocatore);
				ordina();
				return v;
			} catch (Exception e) {
				// TODO: handle exception
				return false;
			}
		}
		else if(!isSingolo && (giocatore instanceof Squadra)){
			try {
				boolean v = 
						!Utility.isThereGiocatore(giocatori, giocatore) && 
						giocatori.size()<maxComponenti &&
						!Utility.isEqualsSquadre(giocatori, (Squadra)giocatore) &&
						giocatori.add(giocatore);
				ordina();
				return v;
			} catch (Exception e) {
				// TODO: handle exception
				return false;
			}
		}else
			return false;
	}

	public boolean removeGiocatore(GiocatoreInterface giocatore) {
		try {
			boolean v =
					Utility.isThereGiocatore(giocatori, giocatore) &&
					giocatori.size()>minComponenti &&
					giocatori.remove(giocatore);
					ordina();
					return v;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
	}

	public GiocatoreInterface getGiocatoreAtPosition(int position) {
		return (position>=0 && giocatori.size()>0)?giocatori.get(position):null;
	}

	public ArrayList<GiocatoreInterface> getGiocatori() {
		return giocatori;
	}

	/**
	 * 
	 * @param giocatori
	 * @throws IllegalArgumentException
	 */
	public boolean setGiocatori(ArrayList<? extends GiocatoreInterface> giocatori) throws IllegalArgumentException{
		if(giocatori.size()<=maxComponenti){
			this.giocatori = (ArrayList<GiocatoreInterface>) giocatori;
			ordina();
			return true;
		}else
			return false;
	}

	/**
	 * 
	 * @param giocatore
	 * @param punti
	 * @return 
	 * @throws IllegalArgumentException
	 */
	public boolean assegnaPunti(GiocatoreInterface giocatore, int punti){
		if(Utility.isThereGiocatore(giocatori, giocatore)){
			if(punti<0)
				return false;
			else
			{
				for(GiocatoreInterface g: giocatori)
					if(g.equals(giocatore))
						g.setTotale_punti(g.getTotale_punti()+punti);
				ordina();
				return true;
			}
		}
		else
			return false;
	}

	/**
	 * 
	 * @param giocatore
	 * @param punti
	 * @throws IllegalArgumentException
	 */
	public boolean penalizzaPunti(GiocatoreInterface giocatore, int punti){
		if(Utility.isThereGiocatore(giocatori, giocatore)){
			if(punti<0)
				return false;
			else
			{
				for(GiocatoreInterface g: giocatori)
					if(g.equals(giocatore))
						g.setTotale_punti(g.getTotale_punti()-punti);
				ordina();
				return true;
			}
		}
		else
			return false;
	}

}
